#
#    Copyright (c) 2009 Corey Goldberg (corey@goldb.org)
#    License: GNU GPLv3
#
#    This file is part of PerfMetrics.
#    
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.  See the GNU General Public License 
#    for more details.
#
#
#    Download the Windows version of RRDTool from:
#      http://www.gknw.net/mirror/rrdtool/
# 
#    You may need these fonts if RRDTool throws an error when you graph:
#      http://dejavu.sourceforge.net/wiki/index.php/Main_Page
#



import os
import time
from subprocess import Popen, PIPE, STDOUT



class RRD(object):
    def __init__(self, rrd_name):
        self.rrd_exe = 'rrdtool'
        self.graph_directory = ''
        self.rrd_directory = ''        
        self.rrd_name = rrd_name
        self.vertical_label = ''
        self.graph_color = '#000000'
        self.graph_width = 380
        self.graph_height = 150
        

    def create(self, interval_secs, ds_type='GAUGE'):  
        interval_mins = interval_secs / 60.0  
        heartbeat = interval_secs * 2
        cmd_create = ''.join((self.rrd_exe, 
            ' create %s' % (self.rrd_directory + self.rrd_name), 
            ' --step %i' % interval_secs, 
            ' DS:values:%s:%i:U:U' % (ds_type, heartbeat),
            ' RRA:AVERAGE:0.5:1:%i' % int(4000 / interval_mins),
            ' RRA:AVERAGE:0.5:%i:800' % int(30 / interval_mins),
            ' RRA:AVERAGE:0.5:%i:800' % int(120 / interval_mins),
            ' RRA:AVERAGE:0.5:%i:800' % int(1440 / interval_mins)))
        cmd_args = cmd_create.split(' ')
        p = Popen(cmd_args, stdout=PIPE, stderr=STDOUT, shell=True)
        cmd_output = p.stdout.read()
        if len(cmd_output) > 0:
            raise RRDException('Unable to create RRD: ' + cmd_output.rstrip())
        
  
    def update(self, value):   
        cmd_update = '%s update %s%s N:%i' % (self.rrd_exe, self.rrd_directory, self.rrd_name, int(value))
        cmd_args = cmd_update.split(' ')
        p = Popen(cmd_args, stdout=PIPE, stderr=STDOUT, shell=True)
        cmd_output = p.stdout.read()
        if len(cmd_output) > 0:
            raise RRDException('Unable to update RRD: ' + cmd_output.rstrip())
    
    
    def graph(self, mins, upper_limit=None):       
        start_time = 'now-%s' % (mins * 60)  
        output_filename = '%s_%i.png' % (self.rrd_name, mins)
        end_time = 'now'
        ds_name = 'values'
        cur_date = time.strftime('%m/%d/%Y %H\:%M\:%S', time.localtime())
        graph_location = self.graph_directory + output_filename        
        cmd_args = []
        cmd_args.append(self.rrd_exe)
        cmd_args.append('graph')
        cmd_args.append(graph_location)
        cmd_args.append('DEF:' + ds_name + '=' + self.rrd_directory + self.rrd_name + ':' + ds_name + ':AVERAGE')
        cmd_args.append('AREA:' + ds_name + self.graph_color)
        cmd_args.append('VDEF:' + ds_name + 'last=' + ds_name + ',LAST')
        cmd_args.append('VDEF:' + ds_name + 'avg=' + ds_name + ',AVERAGE')
        cmd_args.append('COMMENT:  ' + cur_date)
        cmd_args.append('GPRINT:' + ds_name + 'avg:      avg\: %.2lf%S')
        cmd_args.append('GPRINT:' + ds_name + 'last:last\: %.2lf%S')
        #cmd_args.append('--title=' + self.rrd_name.replace('.rrd', ''))
        cmd_args.append('--start=' + start_time)
        cmd_args.append('--end=' + end_time)
        cmd_args.append('--width=' + str(self.graph_width))
        cmd_args.append('--height=' + str(self.graph_height))
        cmd_args.append('--slope-mode')
        cmd_args.append('--lower-limit=0')
        cmd_args.append('--vertical-label=' + self.vertical_label)
        if upper_limit:    
            cmd_args.append('--upper-limit=' + str(upper_limit))
        p = Popen(cmd_args, stdout=PIPE, stderr=STDOUT, shell=True)
        cmd_output = p.stdout.read()
        if len(cmd_output) > 10:
            raise RRDException('Unable to graph RRD: ' + cmd_output.rstrip())
            
          
          
class RRDException(Exception): pass
